/**
 * fshows.com
 * Copyright (C) 2013-2019 All Rights Reserved.
 */
package com.example.fardemo.jmh.counter.impl;

import com.example.fardemo.jmh.counter.ICounter;
import com.example.fardemo.jmh.counter.impl.disruptor.LongEvent;
import com.example.fardemo.jmh.counter.impl.disruptor.LongEventFactory;
import com.example.fardemo.jmh.counter.impl.disruptor.LongEventHandler;
import com.example.fardemo.jmh.counter.impl.disruptor.SimpleThreadFactory;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SleepingWaitStrategy;
import com.lmax.disruptor.WaitStrategy;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 基于disruptor的计数器
 *
 * @author Liluqing
 * @version DisruptorCounter.java, v 0.1 2019-05-07 19:43
 */
public class DisruptorCounter implements ICounter {

    public static long num;

    private Disruptor<LongEvent> disruptor;
    private RingBuffer<LongEvent> ringBuffer;

    public DisruptorCounter() {
        WaitStrategy BLOCKING_WAIT = new YieldingWaitStrategy();
        EventFactory<LongEvent> eventFactory = new LongEventFactory();
        // RingBuffer 大小，必须是 2 的 N 次方；
        int ringBufferSize = 1024 * 1024 * 8;
        disruptor = new Disruptor<>(eventFactory,
                ringBufferSize, new SimpleThreadFactory(), ProducerType.MULTI, BLOCKING_WAIT);
        EventHandler<LongEvent> eventHandler = new LongEventHandler();
        disruptor.handleEventsWith(eventHandler);
        disruptor.start();
        ringBuffer = disruptor.getRingBuffer();
    }

    @Override
    public void hit() {
        ringBuffer.publish(ringBuffer.next());
    }

    @Override
    public long getRequestSum() {
        return num;
    }

    @Override
    public void close() {
        disruptor.shutdown();
    }
}